#!/usr/bin/python

# Author : Amrut Joshi (amrut.joshi@gmail.com)

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

import os
import threading
import time
import sys
from subprocess import Popen, PIPE
import warnings
warnings.simplefilter("ignore",DeprecationWarning)

import gdata
from gdata.docs import service
import getpass
import mimetypes

done = False

filename = ".gdoctoken"

def login_client():
	client = service.DocsService()
	try:
		f = open(filename)
		token = f.read()
		client.SetClientLoginToken(token)
		f.close()
	except IOError:
		(valid, client.email) = get_value("Google Account e-mail address:")
		if not valid:
			sys.exit(0)
		(valid, client.password) = get_value("Google Account password: ", hide=True)
		if not valid:
			sys.exit(0)
		if not client.email or not client.password:
			show_info("Invalid username/password")
			sys.exit(0)
		client.ProgrammaticLogin()
	try:
		token = client.GetClientLoginToken()
		f = open(filename, "w")
		f.write(token)
		f.close()
	except gdata.service.BadAuthentication:
		show_info("Invalid username/password")
		sys.exit(0)
	return client

def start_upload(client, ms, file_path):
	global done
	entry = client.UploadDocument(ms,file_path.split("/")[-1])
	done = True
	

def upload_doc():
	import gdata
	failed_uploads = []
	successful_uploads = []
	client = login_client()
	if not client:
		show_info("Could not login to Google Doc.")
		return

	file_list =  os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].split("\n")
	
	for file_path in file_list[:-1]:
		type = mimetypes.guess_type(file_path)

		if type[0] not in service.SUPPORTED_FILETYPES.values():
			show_info("Unknown file type for %s" % file_path)
			failed_uploads.append(file_path)
			continue

		ms = gdata.MediaSource(file_path = file_path, content_type = type[0])
		threading.Thread(target=start_upload, args=[client, ms, file_path.split("/")[-1]]).start()
		progress_text = "Uploading %s.." % file_path
		x = show_progress(text = progress_text)
		perc = 0
		while not done :
			if perc < 90:
				perc = perc + 5
			show_progress(update="%d" % perc, proc=x, text=progress_text)
			time.sleep(1)
		show_progress(update="100", proc=x, text=progress_text)
		successful_uploads.append(file_path)
	report = ""
	if len(successful_uploads):
		report = report + "\n\nFollowing docs were succesfully uploaded :\n * " + "\n * ".join(successful_uploads)
	if len(failed_uploads):
		report = report + "\n\nFollowing docs were not uploaded :\n * " + "\n * ".join(failed_uploads)
	show_info(report)

def show_info(text):
	proc=Popen("zenity --info --text='%s'" % text, shell=True )
	val = proc.communicate()
	if not proc.returncode:
		return val
	return None

def get_value(text, hide=False):
	if hide:
		proc=Popen("zenity --entry --text='%s' --hide-text" % text, shell=True, stdout=PIPE)
	else:
		proc=Popen("zenity --entry --text='%s'" % text, shell=True, stdout=PIPE)
	val = proc.communicate()
	if not proc.returncode:
		return (not proc.returncode, val[0].strip())
	return (not proc.returncode, None)

def show_progress(update=False, proc=None, text=""):
	if not update:
		proc=Popen("zenity --text '%s' --progress --percentage=0 --auto-close" % text, stdin=PIPE, shell=True)
	else:
		proc.stdin.write("%s\n"%update)
	return proc
	
def main():
	try:
		upload_doc()
	except gdata.service.RequestError:
		os.unlink(filename)
		upload_doc()

if __name__ == "__main__":
	main()
